home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / SmallTalk / CStruct.st < prev    next >
Text File  |  1995-08-25  |  6KB  |  200 lines

  1. "======================================================================
  2. |
  3. | Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
  4. | Written by Steve Byrne.
  5. |
  6. | This file is part of GNU Smalltalk.
  7. |
  8. | GNU Smalltalk is free software; you can redistribute it and/or modify it
  9. | under the terms of the GNU General Public License as published by the Free
  10. | Software Foundation; either version 1, or (at your option) any later version.
  11. | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  12. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  13. | FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  14. | details.
  15. | You should have received a copy of the GNU General Public License along with
  16. | GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  17. | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  18. |
  19.  ======================================================================"
  20.  
  21. "
  22. |     Change Log
  23. | ============================================================================
  24. | Author       Date       Change 
  25. | sbb         16 Feb 92      created summer 90.
  26. |
  27. "
  28.  
  29. CObject variableWordSubclass: #CStruct
  30.     instanceVariableNames: ''
  31.     classVariableNames: 'typeMap'
  32.     poolDictionaries: ''
  33.     category: 'C structures'
  34. !
  35.  
  36.  
  37. !Integer methodsFor: 'extension'!
  38.  
  39. alignTo: anInteger
  40.     "Like ceilingTo (if there were one)"
  41.     "^(self + anInteger - 1) // anInteger * anInteger"
  42.     ^(self + anInteger - 1) truncateTo: anInteger
  43. ! !
  44.  
  45.  
  46.  
  47. !CStruct class methodsFor: 'instance creation'!
  48.  
  49. initialize
  50.     typeMap _ Dictionary new.
  51.     typeMap at: #long put: #CLongType; 
  52.         at: #uLong put: #CULongType;
  53.         at: #char put: #CCharType;
  54.         at: #uChar put: #CUCharType;
  55.         at: #short put: #CShortType;
  56.         at: #uShort put: #CUShortType;
  57.         at: #float put: #CFloatType;
  58.         at: #double put: #CDoubleType;
  59.         at: #string put: #CStringType.
  60. !
  61.  
  62.  
  63. newStruct: structName declaration: array
  64.     | type name newClass offset maxAlignment str inspStr |
  65.     newClass _ CStruct variableWordSubclass: structName asSymbol
  66.                instanceVariableNames: ''
  67.                classVariableNames: ''
  68.                poolDictionaries: ''
  69.                category: 'Synthetic Class'.
  70.  
  71.     offset _ 0.
  72.     maxAlignment _ 1.
  73.     inspStr _ WriteStream on: (String new: 8).
  74.     inspStr nextPutAll: 'inspect'; nl.
  75.     "Iterate through each member, doing alignment, size calculations,
  76.      and creating accessor methods"
  77.     array do:
  78.     [ :dcl | name _ dcl at: 1.
  79.          type _ dcl at: 2.
  80.          self emitInspectTo: inspStr for: name.
  81.    "stdout nextPutAll: 'name is '; nextPutAll: name; nl;
  82.        nextPutAll: 'type is '; nextPutAll: type printString; nl."
  83.          self computeTypeString: type block:
  84.              [ :size :alignment 
  85.                :typeString | 
  86.     "offset printNl."
  87.                      
  88.                      offset _ offset alignTo: alignment.
  89.     "stdout nextPutAll: 'size '.  size printNl.
  90.     stdout nextPutAll: 'offset: '; nextPutAll: offset printString; 
  91.     nextPutAll: ' alignment '; nextPutAll: alignment printString; nl."
  92.     "stdout nextPutAll: 'typestring '; nextPutAll: typeString; nl."
  93.                      maxAlignment _ alignment max: 
  94.                      maxAlignment.
  95.                      str _ WriteStream on: (String new: 20).
  96.                      str nextPutAll: name;
  97.                      nextPutAll: '
  98.     ^self at: '; nextPutAll: offset printString;
  99.                      nextPutAll: ' type: ', typeString.
  100. " str contents printNl.
  101.     stdout nextPutAll: 'size '.  size printNl."
  102.                      newClass compile: str contents.
  103.                      offset _ offset + size
  104.                      ]
  105.              ].
  106.     newClass compile: inspStr contents.
  107.     self compileSize: offset align: maxAlignment for: newClass.
  108.     newClass class compile: 'new
  109.     ^self alloc: self sizeof'
  110. !                    
  111.             
  112.             
  113. computeTypeString: type block: aBlock
  114.     | typeClass typeClassName |
  115.     type class == Array
  116.     ifTrue: [ self computeAggregateType: type block: aBlock ]
  117.     ifFalse:        "must be a type name, either built in or 
  118.                  struct"
  119.         [ typeClassName _ typeMap at: type
  120.                   ifAbsent: [ nil ].
  121.           typeClassName notNil
  122.           ifTrue: [ typeClass _ Smalltalk at: typeClassName.
  123.                 aBlock value: typeClass subType sizeof
  124.                    value: typeClass subType alignof
  125.                    value: typeClassName ]
  126.           ifFalse: [ typeClass _ Smalltalk at: type.
  127.                  aBlock value: typeClass sizeof
  128.                     value: typeClass alignof
  129.                     value: '(CType baseType: ', type, ')' ]
  130.           ]
  131. !
  132.  
  133. computeAggregateType: type block: aBlock
  134.     "Format:
  135.         (array int 3)
  136.         (ptr FooStruct)
  137.     "
  138.     | structureType |
  139.     " ### Should check for 2 or 3 elts only "
  140.     structureType _ type at: 1.
  141.     structureType == #array 
  142.     ifTrue: [ ^self computeArrayType: type block: aBlock ].
  143.     structureType == #ptr
  144.     ifTrue: [ ^self computePtrType: type block: aBlock ].
  145. !
  146.     
  147. computeArrayType: type block: aBlock
  148.     | numElts subType |
  149.     subType _ type at: 2.
  150.     numElts _ type at: 3.
  151.     self computeTypeString: subType
  152.      block: [ :size :alignment 
  153.           :typeString | aBlock value: size * numElts
  154.                        value: alignment
  155.                        value: '(CType baseType: CArray ',
  156.                            'subType: ', typeString,
  157.                                            ' numElements: ',
  158.                                    (numElts printString),
  159.                               ')' ]
  160. !
  161.  
  162. computePtrType: type block: aBlock
  163.     | subType |
  164.     subType _ type at: 2.
  165.     self computeTypeString: subType
  166.      block: [ :size :alignment 
  167.           :typeString | aBlock value: CPtr sizeof
  168.                        value: CPtr alignof
  169.                        value: '(CType baseType: CPtr
  170.                               subType: ', typeString,
  171.                               ')' ]
  172. !
  173.  
  174.  
  175. compileSize: size align: alignment for: aClass
  176.     size _ size alignTo: alignment.
  177.     aClass compile: 'sizeof
  178.     ^self class sizeof'.
  179.     aClass compile: 'alignof
  180.     ^self class alignof'.
  181.     aClass class compile: 'sizeof
  182.     ^', (size printString).
  183.     aClass class compile: 'alignof
  184.     ^', (alignment printString)
  185. !
  186.  
  187. emitInspectTo: str for: name
  188.     str nextPutAll: '    stdout nextPutAll: ''';
  189.     nextPutAll: name;
  190.     nextPutAll: ':''.'; nl.
  191.     str nextPutAll: '    self ';
  192.     nextPutAll: name;
  193.     nextPutAll: ' inspect.'; nl
  194. !!
  195.  
  196. CStruct initialize!
  197.  
  198.